#include "settings.h"

// Qt Includes
#include <QDomElement>

#include <QtDebug>

// ------------------------------------------------------------------
// Construction & Destruction
// ------------------------------------------------------------------
CSettings::CSettings(const QString &strName/* = QString()*/)
    : m_strName(strName)
{

}

// ------------------------------------------------------------------
// Member Functions
// ------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////
// Options
/////////////////////////////////////////////////////////////////////
void CSettings::setOptionByName(const QString &strName, const COption &option)
{
    m_mapOptions.insert(strName, option);
}

COption CSettings::getOptionByName(const QString &strName) const
{
    return m_mapOptions.value(strName);
}

int CSettings::getOptionCount() const
{
	return m_mapOptions.count();
}

const QMap<QString, COption>& CSettings::getAllOptions() const
{
    return m_mapOptions;
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Settings
/////////////////////////////////////////////////////////////////////
void CSettings::setSettingsByName(const QString &strName, const CSettings &settings)
{
    m_mapSettings.insert(strName, settings);
}

CSettings CSettings::getSettingsByName(const QString &strName)
{
    return m_mapSettings.value(strName);
}

int CSettings::getSettingsCount() const
{
	return m_mapSettings.count();
}

const QMap<QString, CSettings>& CSettings::getAllSettings() const
{
    return m_mapSettings;
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Serialisation
/////////////////////////////////////////////////////////////////////
bool CSettings::saveSettings(QDomDocument &domDocument, QDomElement &domElement) const
{
    if(!m_strName.isEmpty())
		domElement.setAttribute(QObject::tr("name"), m_strName);

    QList<QDomElement> lstDomElements;
    QMap<QString, COption>::const_iterator itOptions;

    for(itOptions = m_mapOptions.constBegin(); itOptions != m_mapOptions.constEnd(); itOptions++)
    {
		QDomElement domOption = domDocument.createElement(QObject::tr("option"));

		if(!itOptions.value().saveOption(domDocument, domOption))
			return false;

		domOption.setAttribute(QObject::tr("name"), itOptions.key());
		lstDomElements.append(domOption);
    }

    QMap<QString, CSettings>::const_iterator itSettings;

    for(itSettings = m_mapSettings.constBegin(); itSettings != m_mapSettings.constEnd(); itSettings++)
    {
		QDomElement domSettings = domDocument.createElement(QObject::tr("settings"));

		if(!itSettings.value().saveSettings(domDocument, domSettings))
			return false;

		domSettings.setAttribute(QObject::tr("name"), itSettings.key());

		lstDomElements.append(domSettings);
    }

    QList<QDomElement>::const_iterator itElements;

    for(itElements = lstDomElements.constBegin(); itElements != lstDomElements.constEnd(); itElements++)
	domElement.appendChild(*itElements);

    return true;
}

bool CSettings::loadSettings(const QDomElement &domElement)
{
    QDomNodeList lstChildNodes = domElement.childNodes();
    const int nChildNodeCount = lstChildNodes.count();

    for(int i = 0; i < nChildNodeCount; i++)
    {
		QDomNode domNode = lstChildNodes.at(i);

		if(domNode.isNull())
			continue;

		if(domNode.nodeType() != QDomNode::ElementNode)
			continue;

		const QString strNodeName = domNode.nodeName();

		if(strNodeName == QObject::tr("option"))
		{
			COption theOption;
			const QDomElement domOption = domNode.toElement();

			theOption.loadOption(domOption);
			m_mapOptions.insert(domOption.attribute(QObject::tr("name"), QObject::tr("unnamed")), theOption);
		}
		else if(strNodeName == QObject::tr("settings"))
		{
			CSettings theSettings;
			const QDomElement domSettings = domNode.toElement();

			theSettings.loadSettings(domSettings);
			m_mapSettings.insert(domSettings.attribute(QObject::tr("name"), QObject::tr("unnamed")), theSettings);
		}
    }

    return true;
}
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
// Convenience Functions
/////////////////////////////////////////////////////////////////////
bool CSettings::hasOption(const QString &strOptionName) const
{
    return m_mapOptions.contains(strOptionName);
}

bool CSettings::hasSettings(const QString &strSettingsName) const
{
    return m_mapSettings.contains(strSettingsName);
}
/////////////////////////////////////////////////////////////////////
